unit visuals;
interface
uses
  SysUtils, Bass, vis_list, stl_types;

const
  _INIT_NAME = 'VIS_INIT';
  _RUN_NAME = 'VIS_RUN';
  _FREE_NAME = 'VIS_FREE';

procedure Unload_Visualization;
procedure  Run_Visualization(const p_hndl: Thandle);
procedure INit_Visualization(const id: Cardinal; const Width, Height: Longint; const WAVE, FFT: pointer);
function check_visualization(const file_path: string; var data: TD): boolean;
function Reg_Visualization(const file_path: string): Cardinal;

var
  lst: Tvis_list;

implementation
{$IFDEF FPC}
{$MODE DELPHI}

{$ENDIF}
uses
  {$IFDEF FPC}
             dynLibs, dl
     {$ELSE}
            Windows
     {$ENDIF};
 var
    curr_id: DWORD;
    curr_vis: TD;
function Reg_visualization(const file_path: string): Cardinal;
var
  dt: TD;
  res: Cardinal;
begin
  res := 0;
  if (lst = nil) then
    lst := Tvis_list.Create;
  if check_visualization(file_path, dt) then
  begin
    lst.push_back(file_path);
    res := lst.size;
  end;
  Reg_visualization := res;
end;

function Load_Visualization(file_path: string): Td;
var
  data: Td;
  pnt: pointer;
begin
  data.file_path := file_path;
  {$IFDEF MSWINDOWS}
          data.hndl := LoadLibrary(pchar(file_path));
  {$ELSE}
         file_path := '//usr//lib//libsample.so';
         if (SysUtils.fileExists(file_path)) then
            data.hndl := LoadLibrary(pchar(file_path));
         pnt := nil;
         pnt := dlopen(pchar(file_path), RTLD_LAZY);
  {$ENDIF}
  @data.p_init := nil;
  @data.p_run := nil;
  @data.p_free := nil;
  if (data.hndl > 32) then
  begin
    data.p_init := GetProcAddress(data.hndl, pchar(_INIT_NAME));
    data.p_run := getProcAddress(data.hndl, pchar(_RUN_NAME));
    data.p_free := getProcAddress(data.hndl, pchar(_FREE_NAME));
  end;
  Load_Visualization := data;
end;

function check_visualization(const file_path: string; var data: Td): boolean;
var
    res: bool;
begin
  res := false;
  data := Load_Visualization(file_path);
  with data do
    res := ((@p_init <> nil) and (@p_run <> nil) and (@p_free <> nil));
  check_visualization := res;
  if (data.hndl > 32) then
   //  FreeLibrary(data.hndl);
end;

procedure Unload_Visualization;
begin
  if (curr_vis.hndl > 32) then
  begin
    curr_vis.p_free;
   // FreeLibrary(curr_vis.hndl);
  end;
end;

procedure Run_Visualization(const p_hndl: Thandle);
begin
  curr_vis.p_run(p_hndl);
end;

procedure INit_Visualization(const id: Cardinal; const Width, Height: Longint; const WAVE, FFT: pointer);
var
  data: TD;
begin
  if (id <= lst.size)and(id <> curr_id) then
  begin
     Unload_Visualization;
     curr_vis := Load_Visualization(lst.get(id));
     curr_vis.p_init(Width, Height, WAVE, FFT);
  end;
end;

initialization
  curr_id := 0;
  fillchar(curr_vis, sizeof(curr_vis), 0);
finalization
  Unload_Visualization;
  if (lst <> nil) then
     lst.Free;
end.
